package xyz.lwm.lazycat.netpipe.common.endec;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import xyz.lwm.lazycat.netpipe.common.protocol.Headers;
import xyz.lwm.lazycat.netpipe.common.protocol.Message;
import xyz.lwm.lazycat.netpipe.common.protocol.MsgType;
import xyz.lwm.lazycat.netpipe.common.serial.Serialization;
import xyz.lwm.lazycat.utility.Assert;

/**
 * <h3>消息编码器</h3>
 * F|msgType|headersLength|headers|dataLength|data
 *
 * @author lwm
 */
class MessageEncoder extends MessageToByteEncoder<Message> {

    private final Serialization serialization;

    public MessageEncoder(Serialization serialization) {
        this.serialization = serialization;
    }

    @Override
    protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception {
        // write magic number
        out.writeByte('F');

        // write msgType
        MsgType msgType = msg.getMsgType();
        Assert.notNull(msgType, "msgType");
        out.writeInt(msgType.code);

        // write headers
        Headers headers = msg.getHeaders();
        byte[] headerBytes = headers == null ? new byte[0] : serialization.serialize(headers);
        out.writeInt(headerBytes.length);
        out.writeBytes(headerBytes);

        // write data
        byte[] data = msg.getData();
        data = data == null ? new byte[0] : data;
        out.writeInt(data.length);
        out.writeBytes(data);
    }

}
